home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / manageme / tcpdump-.001 / tcpdump-~ / tcpdump-3.0.2-linux / tcpdump-3.0.2 / print-domain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-15  |  6.0 KB  |  277 lines

  1. /*
  2.  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. #ifndef lint
  23. static char rcsid[] =
  24.     "@(#) $Header: print-domain.c,v 1.23 94/06/14 20:17:38 leres Exp $ (LBL)";
  25. #endif
  26.  
  27. #include <sys/param.h>
  28. #include <sys/time.h>
  29. #include <sys/types.h>
  30. #include <sys/socket.h>
  31.  
  32. #include <net/if.h>
  33.  
  34. #include <netinet/in.h>
  35. #include <netinet/if_ether.h>
  36. #include <netinet/in_systm.h>
  37. #include <netinet/ip.h>
  38. #include <netinet/ip_var.h>
  39. #include <netinet/udp.h>
  40. #include <netinet/udp_var.h>
  41. #include <netinet/tcp.h>
  42. #include <netinet/tcpip.h>
  43.  
  44. #undef NOERROR                    /* Solaris sucks */
  45. #include <arpa/nameser.h>
  46.  
  47. #include <stdio.h>
  48.  
  49. #include "interface.h"
  50. #include "addrtoname.h"
  51.  
  52. static char *ns_ops[] = {
  53.     "", " inv_q", " stat", " op3", " op4", " op5", " op6", " op7",
  54.     " op8", " updataA", " updateD", " updateDA",
  55.     " updateM", " updateMA", " zoneInit", " zoneRef",
  56. };
  57.  
  58. static char *ns_resp[] = {
  59.     "", " FormErr", " ServFail", " NXDomain",
  60.     " NotImp", " Refused", " Resp6", " Resp7",
  61.     " Resp8", " Resp9", " Resp10", " Resp11",
  62.     " Resp12", " Resp13", " Resp14", " NoChange",
  63. };
  64.  
  65. /* skip over a domain name */
  66. static const u_char *
  67. ns_nskip(register const u_char *cp)
  68. {
  69.     register u_char i;
  70.  
  71.     if (((i = *cp++) & 0xc0) == 0xc0)
  72.         return (cp + 1);
  73.     while (i) {
  74.         cp += i;
  75.         i = *cp++;
  76.     }
  77.     return (cp);
  78. }
  79.  
  80. /* print a domain name */
  81. static void
  82. ns_nprint(register const u_char *cp, register const u_char *bp,
  83.       register const u_char *ep)
  84. {
  85.     register u_int i;
  86.  
  87.     putchar(' ');
  88.     if ((i = *cp++) != 0)
  89.         while (i && cp < ep) {
  90.             if ((i & 0xc0) == 0xc0) {
  91.                 cp = bp + (((i << 8) | *cp) & 0x3fff);
  92.                 i = *cp++;
  93.                 continue;
  94.             }
  95.             do {
  96.                 putchar(*cp++);
  97.             } while (--i);
  98.             putchar('.');
  99.             i = *cp++;
  100.         }
  101.     else
  102.         putchar('.');
  103. }
  104.  
  105. static struct token type2str[] = {
  106.     { T_A,        "A" },
  107.     { T_NS,        "NS" },
  108.     { T_MD,        "MD" },
  109.     { T_MF,        "MF" },
  110.     { T_CNAME,    "CNAME" },
  111.     { T_SOA,    "SOA" },
  112.     { T_MB,        "MB" },
  113.     { T_MG,        "MG" },
  114.     { T_MR,        "MR" },
  115.     { T_NULL,    "NULL" },
  116.     { T_WKS,    "WKS" },
  117.     { T_PTR,    "PTR" },
  118.     { T_HINFO,    "HINFO" },
  119.     { T_MINFO,    "MINFO" },
  120.     { T_MX,        "MX" },
  121.     { T_UINFO,    "UINFO" },
  122.     { T_UID,    "UID" },
  123.     { T_GID,    "GID" },
  124. #ifdef T_UNSPEC
  125.     { T_UNSPEC,    "UNSPEC" },
  126. #endif
  127.     { T_AXFR,    "AXFR" },
  128.     { T_MAILB,    "MAILB" },
  129.     { T_MAILA,    "MAILA" },
  130.     { T_ANY,    "ANY" },
  131.     { 0,        NULL }
  132. };
  133.  
  134. /* print a query */
  135. static void
  136. ns_qprint(register const u_char *cp, register const u_char *bp,
  137.       register const u_char *ep)
  138. {
  139.     const u_char *np = cp;
  140.     register u_int i;
  141.  
  142.     cp = ns_nskip(cp);
  143.  
  144.     if (cp + 4 > ep)
  145.         return;
  146.  
  147.     /* print the qtype and qclass (if it's not IN) */
  148.     i = *cp++ << 8;
  149.     i |= *cp++;
  150.     printf(" %s", tok2str(type2str, "Type%d", i));
  151.     i = *cp++ << 8;
  152.     if ((i |= *cp++) != C_IN)
  153.         if (i == C_ANY)
  154.             printf("(c_any)");
  155.         else
  156.             printf("(Class %d)", i);
  157.  
  158.     putchar('?');
  159.     ns_nprint(np, bp, ep);
  160. }
  161.  
  162.  
  163. /* print a reply */
  164. static void
  165. ns_rprint(register const u_char *cp, register const u_char *bp,
  166.       register const u_char *ep)
  167. {
  168.     register u_int i;
  169.     u_short typ;
  170.  
  171.     cp = ns_nskip(cp);
  172.  
  173.     if (cp + 10 > ep)
  174.         return;
  175.  
  176.     /* print the type/qtype and class (if it's not IN) */
  177.     typ = *cp++ << 8;
  178.     typ |= *cp++;
  179.     i = *cp++ << 8;
  180.     if ((i |= *cp++) != C_IN)
  181.         if (i == C_ANY)
  182.             printf("(c_any)");
  183.         else
  184.             printf("(Class %d)", i);
  185.  
  186.     /* ignore ttl & len */
  187.     cp += 6;
  188.     printf(" %s", tok2str(type2str, "Type%d", typ));
  189.     switch (typ) {
  190.  
  191.     case T_A:
  192.         printf(" %s", ipaddr_string(cp));
  193.         break;
  194.  
  195.     case T_NS:
  196.     case T_CNAME:
  197.     case T_PTR:
  198.         ns_nprint(cp, bp, ep);
  199.         break;
  200.  
  201.     case T_MX:
  202.         ns_nprint(cp+2, bp, ep);
  203. #ifndef TCPDUMP_ALIGN
  204.         printf(" %d", *(short *)cp);
  205. #else
  206.         {
  207.             u_short x = *cp | cp[1] << 8;
  208.             printf(" %d", ntohs(x));
  209.         }
  210. #endif
  211.         break;
  212.     }
  213. }
  214.  
  215. void
  216. ns_print(register const u_char *bp, int length)
  217. {
  218.     register const HEADER *np;
  219.     int qdcount, ancount, nscount, arcount;
  220.     const u_char *ep = snapend;
  221.  
  222.     np = (const HEADER *)bp;
  223.     /* get the byte-order right */
  224.     qdcount = ntohs(np->qdcount);
  225.     ancount = ntohs(np->ancount);
  226.     nscount = ntohs(np->nscount);
  227.     arcount = ntohs(np->arcount);
  228.  
  229.     if (np->qr) {
  230.         /* this is a response */
  231.         printf(" %d%s%s%s%s%s",
  232.             ntohs(np->id),
  233.             ns_ops[np->opcode],
  234.             ns_resp[np->rcode],
  235.             np->aa? "*" : "",
  236.             np->ra? "" : "-",
  237.             np->tc? "|" : "");
  238.         if (qdcount != 1)
  239.             printf(" [%dq]", qdcount);
  240.         printf(" %d/%d/%d", ancount, nscount, arcount);
  241.         if (ancount)
  242.             ns_rprint(ns_nskip((const u_char *)(np + 1)) + 4,
  243.                   (const u_char *)np, ep);
  244.     }
  245.     else {
  246.         /* this is a request */
  247.         printf(" %d%s%s",
  248.                 ntohs(np->id),
  249.             ns_ops[np->opcode],
  250.             np->rd? "+" : "");
  251.  
  252.         /* any weirdness? */
  253.         if (*(((u_short *)np)+1) & htons(0x6ff))
  254.             printf(" [b2&3=0x%x]", ntohs(*(((u_short *)np)+1)));
  255.  
  256.         if (np->opcode == IQUERY) {
  257.             if (qdcount)
  258.                 printf(" [%dq]", qdcount);
  259.             if (ancount != 1)
  260.                 printf(" [%da]", ancount);
  261.         }
  262.         else {
  263.             if (ancount)
  264.                 printf(" [%da]", ancount);
  265.             if (qdcount != 1)
  266.                 printf(" [%dq]", qdcount);
  267.         }
  268.         if (nscount)
  269.             printf(" [%dn]", nscount);
  270.         if (arcount)
  271.             printf(" [%dau]", arcount);
  272.  
  273.         ns_qprint((const u_char *)(np + 1), (const u_char *)np, ep);
  274.     }
  275.     printf(" (%d)", length);
  276. }
  277.